package com.yhy.form.service.mng;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yhy.common.constants.BusModuleType;
import com.yhy.common.constants.OperateType;
import com.yhy.common.exception.BusinessException;
import com.yhy.common.service.BaseComplexMngService;
import com.yhy.common.utils.JsonUtils;
import com.yhy.common.utils.YhyUtils;
import com.yhy.form.constants.FormDesignConstant;
import com.yhy.form.dao.FormSetMngDao;
import com.yhy.form.dto.FormSetDTO;
import com.yhy.form.service.*;
import com.yhy.form.vo.FormSetContentVO;
import com.yhy.form.vo.FormSetFieldListVO;
import com.yhy.form.vo.FormSetFieldPrivVO;
import com.yhy.form.vo.FormSetFieldVO;
import com.yhy.form.vo.mng.FormSetMngVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;


/*
 *
 *  * *
 *  *  * <br>
 *  *  * <b>功能：</b><br>
 *  *  * <b>作者：</b>yanghuiyaun<br>
 *  *  * <b>日期：</b> 20-1-10 上午11:45 <br>
 *  *  * <b>版权所有：<b>版权所有(C) 2020<br>
 *  *
 *
 */

@Service("formSetMngService")
@Transactional(rollbackFor = Exception.class)
public class FormSetMngService extends BaseComplexMngService<FormSetDTO, FormSetMngVO> {

    @Autowired
    private FormSetMngDao baseMngDao;

    @Autowired
    private FormSetMainService formSetMainService;
    @Autowired
    private FormSetContentService formSetContentService;
    @Autowired
    private FormSetFieldService formSetFieldService;
    @Autowired
    private FormSetFieldListService formSetFieldListService;
    @Autowired
    private FormSetFieldPrivService formSetFieldPrivService;
    @Autowired
    private FormApplyMngService formApplyMngService;

    @Override
    protected FormSetMngDao getBaseMngDao() {
        return baseMngDao;
    }

    @Override
    public String getBusModule() {
        return BusModuleType.MD_DYNAMIC_FORM_MNG.getVal();
    }

    @Override
    public FormSetMainService getBaseMainService() {
        return formSetMainService;
    }

    public List<FormSetMngVO> getFormSetByCode(Set<String> codes) {
        return getBaseMngDao().getFormSetByCode(codes);
    }

    public Boolean hasFormExtendInfoByModuleBusClass(String moduleBusClass,String sysOwnerCpy, String sysGenCode) {
        return getBaseMngDao().hasFormExtendInfoByModuleBusClass(moduleBusClass,sysOwnerCpy, sysGenCode);
    }

    public FormSetMngVO getFormExtendInfoByModuleBusClass(String moduleBusClass,String sysOwnerCpy)  {
        return getBaseMngDao().getFormExtendInfoByModuleBusClass(moduleBusClass,sysOwnerCpy);
    }

    @Override
    protected void beforeSaveOfProcess(FormSetDTO baseDTO) {
        super.beforeSaveOfProcess(baseDTO);
        FormSetMngVO busMainData = baseDTO.getBusMainData();
        if(busMainData.getFormWidth() == null) {
            busMainData.setFormWidth(100);
        }
        if(this.hasFormExtendInfoByModuleBusClass(busMainData.getModuleBusClass(), busMainData.getSysOwnerCpy(), busMainData.getSysGenCode())) {
            throw new BusinessException("该模块的扩展表格已存在.");
        }
    }

    @Override
    protected void afterProcessOfToView(FormSetDTO baseDTO) {
        super.afterProcessOfToView(baseDTO);
        FormSetMngVO busMainData = baseDTO.getBusMainData();

        FormSetContentVO formSetContentVO = formSetContentService.findByMainId(busMainData.getId());
        baseDTO.setFormSetContentVO(formSetContentVO);
    }

    @Override
    protected void processOfToCopy(FormSetDTO baseDTO) {
        super.processOfToCopy(baseDTO);
        FormSetMngVO busMainData = baseDTO.getBusMainData();

        FormSetContentVO formSetContentVO = formSetContentService.findByMainId(busMainData.getOldMainId());
        formSetContentVO.setId(null);
        formSetContentVO.setMainId(null);
        baseDTO.setFormSetContentVO(formSetContentVO);
    }

    @Override
    protected void processOfToAdd(FormSetDTO baseDTO) {
        super.processOfToAdd(baseDTO);
        baseDTO.getBusMainData().setFormType("OA");
    }

    @Override
    protected void beforeDestoryOfProcess(FormSetMngVO busMainData) {
        super.beforeDestoryOfProcess(busMainData);

        //检查该表单 是否存在 待审批的记录
        if(formApplyMngService.checkExistProcessRecord(busMainData.getSysGenCode())) {
            throw new BusinessException("存在待处理的记录不能注销");
        }
    }

    @Override
    protected void beforeSubmitOfProcess(FormSetDTO baseDTO, FormSetMngVO busMainData) {
        super.beforeSubmitOfProcess(baseDTO, busMainData);
    }

    @Override
    public void processBusCommonStateOfValid(FormSetMngVO busMainData) {
        super.processBusCommonStateOfValid(busMainData);
    }

    @Override
    protected void afterProcessCustomDataOfSave(FormSetDTO baseDTO) {
        super.afterProcessCustomDataOfSave(baseDTO);
        FormSetMngVO busMainData = baseDTO.getBusMainData();
        String mainId = busMainData.getId();
        FormSetContentVO formSetContentVO = baseDTO.getFormSetContentVO();
        if (OperateType.CREATE.getVal().equals(baseDTO.getOperateType())) {
            formSetContentVO.setMainId(mainId);
            formSetContentVO.setEnableFlag("Y");
            formSetContentService.insert(formSetContentVO);

            if(StringUtils.isNotBlank(busMainData.getOldMainId())) {
                // 复制或变更时拷贝数据
                String oldMainId = busMainData.getOldMainId();
                List<FormSetFieldVO> formSetFieldVOList = formSetFieldService.findByMainId(oldMainId);
                Map<String,String> fieldIdMap = Maps.newHashMap();
                for (FormSetFieldVO tmpvo : formSetFieldVOList) {
                    tmpvo.setMainId(mainId);
                    tmpvo.setId(null);
                    formSetFieldService.insert(tmpvo);
                    fieldIdMap.put(tmpvo.getFieldControlId(), tmpvo.getId());
                }
                List<FormSetFieldListVO> formSetFieldListVOList = formSetFieldListService.findByMainId(oldMainId,null);
                for (FormSetFieldListVO tmpvo : formSetFieldListVOList) {
                    tmpvo.setMainId(mainId);
                    tmpvo.setId(null);
                    formSetFieldListService.insert(tmpvo);
                }
                List<FormSetFieldPrivVO> formSetFieldPrivVOList = formSetFieldPrivService.findByMainId(oldMainId);
                for (FormSetFieldPrivVO tmpvo : formSetFieldPrivVOList) {
                    tmpvo.setMainId(mainId);
                    tmpvo.setId(null);
                    tmpvo.setFieldId(fieldIdMap.get(tmpvo.getFieldControlId()));
                    formSetFieldPrivService.insert(tmpvo);
                }
            }
        } 
    }

    @Override
    protected void afterProcessCustomDataOfChange(FormSetDTO baseDTO, FormSetMngVO busMainData) {
        super.afterProcessCustomDataOfChange(baseDTO, busMainData);
        FormSetContentVO formSetContentVO = formSetContentService.findByMainId(busMainData.getOldMainId());
        formSetContentVO.setId(null);
        formSetContentVO.setMainId(null);
        baseDTO.setFormSetContentVO(formSetContentVO);
    }

    public void saveFormDesign(FormSetDTO baseDTO) {
        FormSetContentVO formSetContentVO = baseDTO.getFormSetContentVO();
        int updateNum = formSetContentService.update(formSetContentVO);
        if (updateNum <= 0) {
            throw new BusinessException("更新失败,请刷新重试.");
        }
        formSetContentVO.setVersion(formSetContentVO.getVersion() + 1);

        String formJson = formSetContentVO.getFormJson();
        JSONObject formObject = JSONObject.parseObject(formJson);
        JSONArray jsonArray = formObject.getJSONArray(FormDesignConstant.ALL_FIELDS);

        List<FormSetFieldVO> fieldVOList = Lists.newArrayList();
        List<FormSetFieldListVO> formSetFieldListVOList = Lists.newArrayList();

        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            setProcessFormField(jsonObject, fieldVOList, formSetFieldListVOList);
        }

        formSetMainService.updateFormWidth(formSetContentVO.getMainId(), formObject.getInteger(FormDesignConstant.FORM_WIDTH));

        //所有控件的记录处理, 先增加后删除
        String mainId = formSetContentVO.getMainId();
        Map<String, String> existsFieldSets = Maps.newHashMap();
        Map<String, String> existsFieldPrivs = Maps.newHashMap();
        List<FormSetFieldVO> existsFieldVOS = formSetFieldService.findByMainId(mainId);
        existsFieldVOS.stream().forEach(workflowConfigModuleVO -> {
            existsFieldSets.put(workflowConfigModuleVO.getFieldControlId(), workflowConfigModuleVO.getId());
            existsFieldPrivs.put(workflowConfigModuleVO.getFieldControlId(), workflowConfigModuleVO.getPrivFlag());
        });
        for (FormSetFieldVO fieldVO : fieldVOList) {
            fieldVO.setMainId(mainId);
            fieldVO.setEnableFlag("Y");
            fieldVO.setPrivFlag("N");
            if (existsFieldSets.containsKey(fieldVO.getFieldControlId())) {
                fieldVO.setId(existsFieldSets.get(fieldVO.getFieldControlId()));
                fieldVO.setPrivFlag(existsFieldPrivs.get(fieldVO.getFieldControlId()));
                existsFieldSets.remove(fieldVO.getFieldControlId());
                formSetFieldService.update(fieldVO);
                continue;
            }
            formSetFieldService.insert(fieldVO);
        }
        for (String fieldId : existsFieldSets.values()) {
            FormSetFieldVO deleteVo = new FormSetFieldVO();
            deleteVo.setId(fieldId);
            formSetFieldService.deleteById(deleteVo);
        }

        //所有控件列表选项处理
        formSetFieldListService.deleteByMainId(mainId, null);
        for (FormSetFieldListVO fieldVO : formSetFieldListVOList) {
            fieldVO.setMainId(mainId);
            fieldVO.setEnableFlag("Y");
            formSetFieldListService.insert(fieldVO);
        }

    }

    private void setProcessFormField(JSONObject jsonObject,
                                     List<FormSetFieldVO> formSetFieldVOList, List<FormSetFieldListVO> formSetFieldListVOList) {
        JSONObject configInfo = jsonObject.getJSONObject(FormDesignConstant.FIELD_CONFIG_INFO);

        String layout = configInfo.getString(FormDesignConstant.LAYOUT);
        if (FormDesignConstant.COL_FORM_ITEM.equals(layout)) {
            FormSetFieldVO fieldVO = new FormSetFieldVO();
            fieldVO.setFieldType(configInfo.getString(FormDesignConstant.FIELD_TYPE));
            fieldVO.setFieldControlId(jsonObject.getString(FormDesignConstant.FIELD_CONTROL_ID));
            fieldVO.setFieldName(configInfo.getString(FormDesignConstant.FIELD_NAME));
            fieldVO.setFieldDefaultValue(configInfo.getString(FormDesignConstant.FIELD_DEFAULT_VALUE));
            fieldVO.setRequireFlag(configInfo.getBoolean(FormDesignConstant.REQUIRED_FLAG) ? "Y" : "N");
            fieldVO.setPrivFlag("N");
            formSetFieldVOList.add(fieldVO);

            // 列表控件的list处理
            JSONArray fieldListArray = jsonObject.getJSONArray(FormDesignConstant.FIELD_LIST);
            if (fieldListArray != null && fieldListArray.size() > 0) {
                fieldVO.setFieldList(JsonUtils.toJson(fieldListArray));
                for (int j = 0; j < fieldListArray.size(); j++) {
                    JSONObject fieldListObject = fieldListArray.getJSONObject(j);
                    setProcessFormFieldList(fieldListObject, fieldVO.getFieldControlId(), null, formSetFieldListVOList);
                }
            }
        }

        // 容器控件，递归处理
        JSONArray jsonArray = configInfo.getJSONArray(FormDesignConstant.FIELD_CHILDREN);
        if (jsonArray != null && jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject tmpObject = jsonArray.getJSONObject(i);
                setProcessFormField(tmpObject, formSetFieldVOList, formSetFieldListVOList);
            }
        }
    }

    private void setProcessFormFieldList(JSONObject fieldListObject, String fieldControlId, String parentValue, List<FormSetFieldListVO> formSetFieldListVOList) {
        FormSetFieldListVO fieldListVO = new FormSetFieldListVO();
        fieldListVO.setFieldControlId(fieldControlId);
        fieldListVO.setValue(fieldListObject.getString(FormDesignConstant.FIELD_LIST_VALUE));
        fieldListVO.setLabel(fieldListObject.getString(FormDesignConstant.FIELD_LIST_LABEL));
        fieldListVO.setAttribute1(fieldListObject.getString(FormDesignConstant.FIELD_LIST_ATTRIBUTE1));
        fieldListVO.setParentValue(parentValue);

        formSetFieldListVOList.add(fieldListVO);

        // 容器控件，递归处理
        JSONArray jsonArray = fieldListObject.getJSONArray(FormDesignConstant.FIELD_CHILDREN);
        if (jsonArray != null && jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject tmpObject = jsonArray.getJSONObject(i);
                setProcessFormFieldList(tmpObject, fieldControlId, fieldListVO.getValue(), formSetFieldListVOList);
            }
        }
    }


    public void saveFieldPriv(FormSetFieldVO fieldVO, FormSetFieldPrivVO visibleFieldPrivVO, FormSetFieldPrivVO editFieldPrivVO) {
        List<FormSetFieldPrivVO> fieldPrivVOS = formSetFieldPrivService.findByFieldId(fieldVO.getId());
        Map<String, String> configDtls = Maps.newHashMap();
        fieldPrivVOS.stream().forEach(fieldPrivVO -> {
            configDtls.put(fieldPrivVO.getTypeCode() + fieldPrivVO.getTypeValue() + fieldPrivVO.getPrivType(), fieldPrivVO.getId());
        });

        List<FormSetFieldPrivVO> newDetails = formSetFieldPrivService.convertInfo2DetailVO(fieldVO, visibleFieldPrivVO, editFieldPrivVO);
        String privFlag = "N";
        //插入新记录
        for (FormSetFieldPrivVO detailVO : newDetails) {
            privFlag = "Y";
            String busKey = detailVO.getTypeCode() + detailVO.getTypeValue() + detailVO.getPrivType();
            //存在的记录则跳过
            if (configDtls.containsKey(busKey)) {
                configDtls.remove(busKey);
                continue;
            }
            detailVO.setEnableFlag("Y");
            formSetFieldPrivService.insert(detailVO);
        }
        //删除处理
        for (String configId : configDtls.values()) {
            FormSetFieldPrivVO detailVO = new FormSetFieldPrivVO();
            detailVO.setId(configId);
            formSetFieldPrivService.deleteById(detailVO);
        }

        //更新formfield的权限标识(privFlag)
        formSetFieldService.updateFieldPrivFlag(fieldVO.getId(), privFlag);
    }

    public List<FormSetMngVO> buildFormApplyTree(List<FormSetMngVO> mngVOS) {
        Map<String,FormSetMngVO> oaMenuMap = Maps.newHashMap();
        for (FormSetMngVO mngVO : mngVOS) {
            String tmpMenuName = mngVO.getOaMenuName();
            FormSetMngVO tmpMap = oaMenuMap.get(tmpMenuName);
            if(tmpMap == null) {
                FormSetMngVO oaMenu = new FormSetMngVO();
                oaMenu.setFormName(tmpMenuName);
                oaMenu.setFormType(mngVO.getFormType());
                oaMenu.setOaMenuName(tmpMenuName);
                oaMenu.setId(YhyUtils.generateUUID());
                oaMenu.setChildren(Lists.newArrayList());
                tmpMap = oaMenu;

                oaMenuMap.put(tmpMenuName, tmpMap);
            }
            List<FormSetMngVO> tmpList = tmpMap.getChildren();
            tmpList.add(mngVO);
        }
        List<FormSetMngVO> trees = new ArrayList<>();
        trees.addAll(oaMenuMap.values());
        return trees;
    }

}